SSM Session Managerを使ってポートフォワードする
Session Managerについて
Session ManagerはAWS Systems Manager(SSM)の機能の一つです。
Session ManagerはEC2インスタンスなどのエージェントがインストールされたマシンとクライアントの間にセッションを作成してくれます。
特徴としてはホスト側がプル式でセッションを作成するため、セキュリティグループによるポートの開放が不要になります。
不必要にポートを解放する必要がなくなり、セキュリティが向上します。
また、Session Mnagerを利用して通信を行うとアクティビティのログが保存可能で、コンプライアンスの観点からも便利です。
今回は、Session Managerの機能をつかってEC2インスタンスのポートをローカルにポートフォワードしてみたいと思います。
こうすることで、セキュリティグループでポートを解放せずともEC2インスタンスのポートにアクセス可能となります。
準備
EC2インスタンスを用意します。 Session Managerを利用するためには以下の3つの条件が揃っている必要があります。
- SSMのエンドポイントへのアクセスが可能
- SSM Agentがインストールされている
- 適切なIAMロールがインスタンスプロファイルに割り当てられている
今回は以下のようなインスタンスを作成しました。
- Public IPが割り当てられインターネットへのアクセスが可能(SSMのエンドポイントへのアクセスが可能)
- マシンイメージはAmazon Linux 2 (SSM Agentはデフォルトでインストール済み)
AmazonSSMManagedInstanceCore
をインスタンスプロファイルに割り当て済み(インスタンスがSSMにアクセスするのに必要な権限が含まれている)- セキュリティグループのインバウンドは全て拒否、アウトバウンドは全て許可
接続してみる
EC2インスタンスに対してポートフォワードを行ってみます。
$ aws ssm start-session --target i-0123456789ABCDEFG \ --document-name AWS-StartPortForwardingSession \ --parameters '{"portNumber":["22"],"localPortNumber":["10022"]}' Starting session with SessionId: XXXXXXX Port 10022 opened for sessionId XXXXXXX. Waiting for connections... # SSHなどで通信が開始すると以下のメッセージが表示される。 Connection accepted for session [XXXXXXX]
今回は、EC2インスタンスの22番ポートをローカルの10022番にポートフォワードしています。
つまりは、ローカルの10022番を利用して通信を行う場合はすべてEC2インスタンスの22番に転送されます。
試しに、SSHで接続してみます。
$ ssh ec2-user@localhost -p 10022 -i XXXXXXX.pem Last login: Tue Mar 29 06:52:33 2022 from localhost __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/
ローカルホストの10022番に対してアクセスしましたが、EC2インスタンスにつながりました。 無事ポートフォワードが機能していることが確認できました。
このとき注意点として、SSHで接続する場合はEC2に公開鍵が設定されている必要があります。
セッションを作成するまではSSMが行ってくれるので認証情報は必要ありませんが、セッション作成後は単純にSSHでの接続となるので認証情報が必要となります。
今回はsshコマンドの-i
オプションで認証情報のファイルを指定しています。
SSH Configファイルに設定するともっと便利に
SSHで接続するたびに毎回AWS CLIでコマンドを叩くのは冗長かもしれません。
SSHのConfigファイルに以下の内容を記述すればもう少し簡単にアクセスできます。
host i-* mi-* ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
この設定があれば以下のように接続することができます。
$ ssh ec2-user@i-0123456789ABCDEFG -i ./XXXXXXX.pem Last login: Tue Mar 29 17:15:48 2022 from localhost __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/
おまけ
ポートフォワードで通信を行なっているため、ある程度自由にポートを転送することができます。
いろいろなアプリケーションで接続してみます。
SFTP
先ほどと同様にEC2インスタンスの22番ポートをローカルの10022番にポートフォワードすればSFTPも利用可能です。
$ sftp -oPort=10022 -i XXXXXXX.pem ec2-user@localhost Connected to localhost. sftp> put ./dummy.txt Uploading ./dummy.txt to /home/ec2-user/dummy.txt ./dummy.txt 100% 14 0.5KB/s 00:00 sftp> quit
HTTP
次は別のポートで試してみます。 EC2インスタンスにNginxをインストールし80番ポートをローカルの10080番にポートフォワードします。
$ aws ssm start-session --target i-0123456789ABCDEFG \ --document-name AWS-StartPortForwardingSession \ --parameters '{"portNumber":["80"],"localPortNumber":["10080"]}'
先ほどと違うのはポート番号だけです。
cURLを用いて、ローカルの10080番にアクセスしてみます。
$ curl -I http://localhost:10080 HTTP/1.1 200 OK Server: nginx/1.20.0 Date: Tue, 29 Mar 2022 07:19:52 GMT Content-Type: text/html Content-Length: 3520 Last-Modified: Thu, 15 Jul 2021 21:46:50 GMT Connection: keep-alive ETag: "60f0acca-dc0" Accept-Ranges: bytes
無事にNginxからリクエストが返ってきました。